package com.dongdongshop.service.impl;

import com.dongdongshop.bo.CartBO;
import com.dongdongshop.bo.CartDetail;
import com.dongdongshop.constant.CartConstant;
import com.dongdongshop.pojo.TbItem;
import com.dongdongshop.service.CartService;
import com.dongdongshop.service.ItemService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Service
@DubboService
public class CartServiceImpl implements CartService {

    @DubboReference
    private ItemService itemService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 合并购物车数据
     * @param cartBOS
     * @param cartList
     * @return
     */
    @Override
    public List<CartBO> merge(List<CartBO> cartBOS, List<CartBO> cartList) {
        for(CartBO cartBO : cartBOS){
            List<CartDetail> cartDetailList = cartBO.getCartDetailList();
            for(CartDetail detail : cartDetailList){
                cartList = addCart(cartList,detail.getItemId(),detail.getNum());
            }
        }
        return cartList;
    }

    /**
     * 往redis中添加购物车数据
     * @param id
     * @param cartBOS
     */
    @Override
    public void addCartToRedis(Long id, List<CartBO> cartBOS) {
        redisTemplate.boundHashOps(CartConstant.CART_LIST).put(CartConstant.CART_USER + id,cartBOS);
    }

    /** 从redis中取出购物车数据
     *
     * @param
     * @return
     */
    @Override
    public List<CartBO> getCartFromRedis(Long id) {
        List<CartBO> cartBOList = (List<CartBO>) redisTemplate.boundHashOps(CartConstant.CART_LIST).get(CartConstant.CART_USER + id);
        return cartBOList == null || cartBOList.isEmpty() ? new ArrayList<>() : cartBOList;
    }

    /**
     * @param cartList 原来的购物车
     * @param itemId   要买的商品
     * @param num      要买商品的数量
     * @return
     */
    @Override
    public List<CartBO> addCart(List<CartBO> cartList, Long itemId, Integer num) {
        //1.根据商品的id查询商品数据
        TbItem tbItem = itemService.selectItemById(itemId);
        //2.通过商品的数据,获取到商家的id
        String sellerId = tbItem.getSellerId();
        //3.根据商家id判断购物车列表中是否存在该商家的商品
        CartBO bo = getBo(cartList, sellerId);
        if (bo == null) {
            //3.1:没买过,第一次买,创建一个新的商家购物车CartBO ,创建里面的明细等等,最后放到原来的购物车列表中cartList
            bo = new CartBO();
            bo.setSellerId(sellerId);
            //创建购物车明细
            List<CartDetail> cartDetailList = new ArrayList<>();
            CartDetail detail = careateCartDetail(tbItem, num);
            //将创建出来的明细放入到明细列表中
            cartDetailList.add(detail);
            //将明细列表放入到购物车类中
            bo.setCartDetailList(cartDetailList);
            //最后将bo放入到购物车列表中
            cartList.add(bo);
        } else {
            //3.2 买过
            List<CartDetail> cartDetailList = bo.getCartDetailList();
            CartDetail de = getdetail(cartDetailList, tbItem.getId());
            if (de == null) {
                //3.2.1买过这个商家的东西,但不是该商品 拿到这个CartBO,取出cartDetailList,判断里面有没有我们现在要买的东西
                //发现不是  我们需要创建一个CartDetail对象,赋值,追加到cartDetailList中就行了
                de = careateCartDetail(tbItem, num);
                cartDetailList.add(de);

            } else {
                //3.2.2买过这个商家的同一个商品 拿到这个CartBO,取出cartDetailList,判断里面有没有我们现在要买的东西
                //发现有 取出CartDetail对象,修改数据和总价格就行了
                de.setNum(de.getNum() + num);
                de.setTotalFee(new BigDecimal(de.getPrice().doubleValue() * de.getNum()));
                if (de.getNum() <= 0) {
                    //当某一件商品的数量变成0了,我们要将当前的商品从购物车明细列表中移出
                    cartDetailList.remove(de);
                }
                if (cartDetailList.size() == 0) {
                    //当店铺下没有商品时,将该店铺从购物车中移出
                    cartList.remove(bo);
                }
            }
        }
        return cartList;
    }

    //封装
    private CartBO getBo(List<CartBO> cartList, String sellerId) {
        return cartList.stream().filter(b -> Objects.equals(b.getSellerId(), sellerId)).findFirst().orElse(null);
    }

    //封装
    private CartDetail getdetail(List<CartDetail> cartDetailList, Long itemId) {
        return cartDetailList.stream().filter(b -> Objects.equals(b.getItemId(), itemId)).findFirst().orElse(null);
    }

    private CartDetail careateCartDetail(TbItem item, Integer num) {
        CartDetail detail = new CartDetail();
        detail.setImage(item.getImage());
        detail.setItemId(item.getId());
        detail.setName(item.getTitle());
        detail.setNum(num);
        detail.setPrice(item.getPrice());
        detail.setTotalFee(new BigDecimal(item.getPrice().doubleValue() * num));
        return detail;
    }
}
